package remote

import (
	"context"
	"testing"
	"time"

	"gopkg.openfuyao.cn/cluster-api-provider-bke/utils/log"
)

func TestRemoteSSHExec(t *testing.T) {

	host := &Host{
		User:     "root",
		Port:     "22",
		Password: "Ccc51521!",
		Address:  "172.28.100.206",
	}

	cmd := Command{
		Cmds: []string{
			"echo $(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/^unknown$/amd64/')",
		},
	}

	cli, err := NewRemoteClient(host)
	if err != nil {
		t.Fatal(err)
	}

	stdErrChan := make(chan CombineOut)
	stdOutChan := make(chan CombineOut)

	go func() {
		for {
			select {
			case stdErr := <-stdErrChan:
				t.Logf("stdErr: %s", stdErr)
			case stdOut := <-stdOutChan:
				t.Logf("stdOut: %s", stdOut)
			default:
				// do nothing
			}
		}
	}()

	cli.Exec(context.Background(), cmd, stdErrChan, stdOutChan)
}

func TestMultiCli(t *testing.T) {
	commands1 := Command{
		Cmds: []string{
			"sleep 2",
			"echo $(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/^unknown$/amd64/')",
			"echo abc",
		},
	}

	commands2 := Command{
		Cmds: []string{
			"sleep 5",
			"sleep 10",
		},
	}

	hosts := []Host{
		{
			User:     "root",
			Address:  "172.28.100.206",
			Port:     "22",
			Password: "Ccc51521!",
		},
		{
			User:     "root",
			Address:  "172.28.100.220",
			Port:     "22",
			Password: "Ccc51521!",
		},
	}

	ctx, cancel := context.WithCancel(context.Background())

	multiCli := NewMultiCli(ctx)
	errs := multiCli.RegisterHosts(hosts)
	for _, err := range errs {
		log.Errorf("failed to register hosts: %v", err)
	}

	go func() {
		log.Infof("start")
		<-time.After(8 * time.Second)
		log.Infof("cancel")
		cancel()
	}()

	stdErrs, stdOuts := multiCli.Run(commands1)
	for _, err := range stdErrs.Out() {
		for _, line := range err {
			log.Error(line)
		}
	}
	for _, outs := range stdOuts.Out() {
		for _, line := range outs {
			log.Info(line)
		}
	}

	stdErrs, stdOuts = multiCli.Run(commands2)
	for _, err := range stdErrs.Out() {
		for _, line := range err {
			log.Error(line)
		}
	}
	for _, outs := range stdOuts.Out() {
		for _, line := range outs {
			log.Info(line)
		}
	}
}
